package com.repository.dao;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

import com.repository.exception.ApplicationException;
import com.repository.model.User;

@Repository(value="userDAO")
public class UserDAOImpl implements UserDAO
{

	Log log = LogFactory.getLog(UserDAOImpl.class);

	@Autowired
	HibernateTemplate hibernateTemplate;

	/**
	 * @return the hibernateTemplate
	 */
	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}

	/**
	 * @param hibernateTemplate the hibernateTemplate to set
	 */
	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

	/* (non-Javadoc)
	 * @see com.repository.dao.UserDAO#getUser(java.lang.Long)
	 */
	public User getUser(Long userId)
	{
		this.log.info("entry");

		User user = (User)getHibernateTemplate().get(User.class, userId);

		if (user != null)
			this.log.info("got user " + user.getUserName());
		else {
			this.log.error("user " + userId + " not found");

			throw new ApplicationException("user " + userId + " not found");
		}
		return user;
	}

	/* (non-Javadoc)
	 * @see com.repository.dao.UserDAO#getUsers()
	 */
	public List<User> getUsers()
	{
		List<User> users = getHibernateTemplate().find("from User");

		log.debug("got list of size:" + users.size());

		return users;
	}

	/* (non-Javadoc)
	 * @see com.repository.dao.UserDAO#removeUser(com.repository.model.User)
	 */
	public void removeUser(User user)
	{
		try {

			getHibernateTemplate().delete(user);

			this.log.debug("delete successful");

		} catch (RuntimeException re) {

			this.log.error("delete failed", re);

			throw new ApplicationException(re.getMessage());

		}
	}

	/* (non-Javadoc)
	 * @see com.repository.dao.UserDAO#saveOrUpdateUser(com.repository.model.User)
	 */
	public User saveOrUpdateUser(User user)
	{
		this.log.info("user id:" + user.getId());
		try
		{
			getHibernateTemplate().saveOrUpdate(user);

		} catch (HibernateException e) {

			this.log.error("error in hibernate query" + e);

			throw new ApplicationException(e.getMessage());
		}

		return user;
	}



	/* (non-Javadoc)
	 * @see com.repository.dao.UserDAO#findByProperty(java.lang.String, java.lang.Object)
	 */
	public List findByProperty(String propertyName, Object value)
	{
		this.log.debug("finding User instance with property: " + propertyName + 
				", value: " + value);
		try {
			
			String queryString = "from User as model where model." + 
			propertyName + "= ?";
			
			return getHibernateTemplate().find(queryString, value);
			
		} catch (RuntimeException re) {

			this.log.error("find by property name failed", re);

			throw new ApplicationException(re.getMessage());
		}
	}

	/* (non-Javadoc)
	 * @see com.repository.dao.UserDAO#findByUserIdList(java.util.List)
	 */
	public List<User> findByUserIdList(List<String> userIdList){

		List<User> userList = new ArrayList<User>();

		try {

			userList = getHibernateTemplate().findByNamedQueryAndNamedParam("getUsersByUserIdList", "userIdList", "1,2,3");

		} catch (Exception e) {
			// TODO: handle exception
		}

		return userList;
	}
}